<template>
    <el-card>
        <div>
            <div v-for="p in state" :key="p.id">
                <div class="all">
                    <el-checkbox v-model="p.isCheckAll" :indeterminate="p.isIndeterminate"
                        @change="checkAllChange(p)">{{ p.name }}</el-checkbox>
                </div>
                <el-checkbox-group v-model="p.checkeds" @change="gourpChange(p)">
                    <el-checkbox v-for="c in p.children" :key="c.id" :label="c.id">{{
                        c.name
                    }}</el-checkbox>
                </el-checkbox-group>
            </div>
            <div class="flex">
                <el-button>清空</el-button>
                <el-button type="primary" @click="clickHandle">确定</el-button>
            </div>
        </div>
    </el-card>
</template>

<script setup lang="ts">
import {
    getRourceListByRoleIdApi,
    resourceListAllApi,
    resourceCategoryAllApi,
    allocResourceApi,
} from "./api";
import { useRoute } from "vue-router";
import { ref } from "vue";
const route = useRoute();

type IState = IResourceCategoryModel & {
    children: IResourceModel[];
    // 在这个里面存 当前这个分类选中的id
    checkeds: number[];
    // 是否全选
    isCheckAll: boolean;
    // 是否半选
    isIndeterminate: boolean;
};

let state = ref<IState[]>([]);
if (route.query.id) {
    // 要求三个请求都成功，再组织双层结构
    Promise.all([
        resourceCategoryAllApi(),
        resourceListAllApi(),
        getRourceListByRoleIdApi(parseInt(route.query.id as string)),
    ])
        .then((res) => {
            state.value = res[0].data.map((item) => ({
                ...item,
                children: [],
                checkeds: [],
                isCheckAll: false,
                isIndeterminate: false,
            }));
            res[1].data.forEach((resource) => {
                const cate = state.value.find(
                    (cate) => cate.id === resource.categoryId
                );
                // children 里面的数据是用来渲染的
                cate && cate.children.push(resource);
            });
            res[2].data.forEach((item) => {
                // 把 已经有的 资源的id，放到 p.checkeds 里面，让页面勾选
                const pp = state.value.find((p) => p.id === item.categoryId);
                pp && pp.checkeds.push(item.id);
            });
            state.value.forEach((pp) => {
                // 处理全选
                pp.isCheckAll = pp.checkeds.length === pp.children.length;
                // 处理半选
                pp.isIndeterminate =
                    pp.checkeds.length > 0 && pp.checkeds.length < pp.children.length;
            });
        })
        .catch(() => { });
}

const checkAllChange = (data: IState) => {
    // 根据点击的全选checkbox的状态，来控制下面的全选与全不选
    if (!data.isCheckAll) {
        data.checkeds = [];
    } else {
        data.checkeds = data.children.map((item) => item.id);
    }
    // 处理半选
    data.isIndeterminate =
        data.checkeds.length > 0 && data.checkeds.length < data.children.length;
};

const gourpChange = (data: IState) => {
    // 处理全选
    data.isCheckAll = data.checkeds.length === data.children.length;
    // 处理半选
    data.isIndeterminate =
        data.checkeds.length > 0 && data.checkeds.length < data.children.length;
};

const clickHandle = () => {
    allocResourceApi({
        roleId: parseInt(route.query.id as string),
        // 把所有勾选的id发回服务器
        resourceIds: state.value.reduce<number[]>((prev, next) => {
            return prev.concat(next.checkeds);
        }, []),
    });
};
</script>

<style scoped>
.all {
    padding: 20px;
    background-color: #f2f6fc;
}

:deep(.el-checkbox-group) {
    display: grid;
    grid-template-columns: repeat(3, 33%);
    padding: 20px;
}

.flex {
    padding: 20px;
    display: flex;
    justify-content: center;
}
</style>